<template>
  <div>
    <div id="container" :class="cursor ? 'cursordown' : 'cursorup'"></div>

    <!-- 公园列表 -->
    <div v-show="show && routeShow" id="part-box">
      <part-list :partList="partList" :click="getClickPart"></part-list>
    </div>
    <!-- 公园详情 -->
    <div class="anim-down" v-show="!show && routeShow" id="part-detail">
      <a :href="`https://www.amap.com/detail/${currentPart.id}`" target="_blank"
        ><img
          style="width: 100%; height: 200px"
          :src="
            currentPart.photos
              ? currentPart.photos[0].url
              : 'http://a.amap.com/jsapi_demos/static/images/search-img-default.png'
          "
      /></a>
      <div id="placereturnfixed" @click="show = true">返回</div>
      <div id="info-box">
        <div id="info">
          <div
            style="
              padding: 15px 5px 10px 5px;
              font-size: 30px;
              font-weight: 300;
            "
          >
            {{ currentPart.name }}
          </div>
          <div style="padding: 5px 5px 10px 5px">
            <i class="el-icon-location-outline"></i>{{ currentPart.address }}
          </div>
          <div v-if="currentPart.tel" style="padding: 5px 5px 10px 5px">
            <i class="el-icon-phone"></i>{{ currentPart.tel }}
          </div>
          <div v-if="currentPart.rating" id="rate" style="padding-left: 5px">
            <el-rate
              :value="parseFloat(currentPart.rating)"
              disabled
              allow-half
              show-score
              text-color="#ff9900"
            >
            </el-rate>
          </div>
        </div>
        <div id="go-btn" @click="routeShow = false">
          <i class="el-icon-s-promotion" style="color: #e5ff1e"></i>
          去这里
        </div>
      </div>
    </div>
    <!-- 公园路线 -->
    <div v-show="!routeShow">
      <div class="anim-down" id="part-route">
        <div
          id="close-route"
          @click="
            routeShow = true;
            if (way) way.clear();
          "
        >
          ×
        </div>
        <div class="goway">
          <div>
            <el-button
              v-for="(w, index) in ['驾车', '公交', '走路']"
              :key="index"
              @click="currentWay = index"
              :type="currentWay == index ? 'success' : 'primary'"
              >{{ w }}</el-button
            >
          </div>
        </div>
        <p class="line-search-from">
          <label>起 </label>
          <input
            type="text"
            class="dir_ipt"
            autofocus
            placeholder="请输入起点"
            :value="dir_from"
            autocomplete="off"
          />
        </p>
        <p class="line-search-from">
          <label>终 </label>
          <input
            type="text"
            class="dir_ipt"
            placeholder="请输入终点"
            :value="dir_to"
            autocomplete="off"
          />
        </p>
        <div id="to-btn" @click="toDestination">
          <i v-if="goLoading" class="el-icon-loading"></i
          ><span v-if="!goLoading">{{ wayTip[currentWay] }}</span>
        </div>
      </div>
      <div id="route-info"></div>
    </div>
    <!-- 工具栏 -->
    <div id="toolbox">
      <nav-menu :adcode="currentAdcode" :partList="partList"></nav-menu>
    </div>
  </div>
</template>

<script>
import AMapLoader from "@amap/amap-jsapi-loader";
import PartList from "./PartList.vue";
import NavMenu from "./NavMenu.vue";
window._AMapSecurityConfig = {
  securityJsCode: "ea3a91e3b6f171104a60234a866c5ed2",
};

export default {
  components: { PartList, NavMenu },
  data() {
    return {
      map: null,
      autoOptions: {
        input: "",
      },
      auto: null,
      //接收Search组件传输input输入框的值
      searchPlaceInput: "",
      lngLat: "",
      wayTip: ["开车去", "坐公交", "走路去"],
      currentAdcode: 0,
      partList: [],
      marker: null,
      show: true,
      routeShow: true,
      currentPart: {},
      currentWay: 0,
      dir_from: "华南农业大学",
      dir_to: "",
      way: null,
      goLoading: false,
      allEvent: true,
      cursor: true,
    };
  },
  methods: {
    // 设置鼠标右击事件
    setMouseRight() {
      //创建右键菜单
      let contextMenu = new AMap.ContextMenu();

      //右键放大
      contextMenu.addItem(
        "放大一级",
        () => {
          this.map.zoomIn();
        },
        0
      );

      //右键缩小
      contextMenu.addItem(
        "缩小一级",
        () => {
          this.map.zoomOut();
        },
        1
      );

      //右键显示全国范围
      contextMenu.addItem(
        "缩放至全国范围",
        () => {
          this.map.setZoomAndCenter(4, [108.946609, 34.262324]);
        },
        2
      );
      this.contextMenu = contextMenu;
      //地图绑定鼠标右击事件——弹出右键菜单
      this.map.on("rightclick", (e) => {
        if (this.allEvent) {
          this.contextMenu.open(this.map, e.lnglat);
        }
      });
    },
    // 获取当前位置路线
    toDestination() {
      // console.log(this.currentWay);
      this.goLoading = true;
      if (this.way) this.way.clear();
      new Promise((resolve, reject) => {
        if (this.currentWay == 0) {
          if (!this.$Driving) {
            this.map.plugin(["AMap.Driving"], () => {
              this.$Driving = new AMap.Driving({
                map: this.map,
                panel: "route-info",
              });
            });
            resolve(this.$Driving);
          } else {
            resolve(this.$Driving);
          }
        } else if (this.currentWay == 1) {
          if (!this.$Transfer) {
            this.map.plugin(["AMap.Transfer"], () => {
              this.$Transfer = new AMap.Transfer({
                map: this.map,
                city: this.currentPart.cityname,
                panel: "route-info",
                policy: AMap.TransferPolicy.LEAST_TIME, //乘车策略
              });
            });
            resolve(this.$Transfer);
          } else {
            resolve(this.$Transfer);
          }
        } else {
          if (!this.$Walking) {
            this.map.plugin(["AMap.Walking"], () => {
              this.$Walking = new AMap.Walking({
                map: this.map,
                panel: "route-info",
              });
            });
            resolve(this.$Walking);
          } else {
            resolve(this.$Walking);
          }
        }
      }).then((v) => {
        this.way = v;
        this.getRoute();
      });
    },
    getRoute() {
      this.way.search(
        [
          { keyword: this.dir_from, city: this.currentPart.cityname },
          { keyword: this.dir_to, city: this.currentPart.adname },
        ],
        (status, result) => {
          // result 即是对应的驾车导航信息，相关数据结构文档请参考  https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
          if (status === "complete") {
            // console.log("绘制路线完成");
            this.goLoading = false;
          } else {
            this.goLoading = false;
            console.log("获取数据失败：" + result);
            this.$message({
              message: "获取数据失败",
              type: "warning",
            });
          }
        }
      );
    },
    // 获取当前点击的公园
    getClickPart(e) {
      if (this.marker) {
        this.map.remove(this.marker);
      }
      let part = this.partList[e];
      this.dir_to = part.name;
      this.currentPart = this.partList[e];
      this.marker = new AMap.Marker({
        position: part.location,
        label: {
          direction: "right",
          offset: new AMap.Pixel(10, 0), //设置文本标注偏移量
          content: part.name, //设置文本标注内容
        },
      });
      this.map.add(this.marker);
      this.map.setFitView(this.marker, false, [200, 200, 200, 200]);
      this.show = false;
    },
    // 地图初始化
    initMap() {
      AMapLoader.load({
        key: "2a41ebeb1883bd428ff62dd054186e6c", // 申请好的Web端开发者Key，首次调用 load 时必填
        version: "2.0", // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
        plugins: [
          "AMap.ToolBar",
          "AMap.Scale",
          "AMap.Geolocation",
          "AMap.ContextMenu",
          "AMap.ControlBar",
        ], // 需要使用的的插件列表，如比例尺'AMap.Scale'等
      })
        .then((AMap) => {
          this.$layer = new AMap.createDefaultLayer(); //是否可见
          this.$satellite = new AMap.TileLayer.Satellite({ visible: false });
          this.$roadNet = new AMap.TileLayer.RoadNet({ visible: false });
          this.$buildings = new AMap.Buildings({ visible: false });
          this.map = new AMap.Map("container", {
            //设置地图容器id
            viewMode: "3D",
            zoom: 10, //初始化地图级别
            center: [113.264499, 23.130061], //初始化地图中心点位置
            layers: [
              this.$buildings,
              this.$layer,
              this.$satellite,
              this.$roadNet,
            ],
          });
          this.map.addControl(new AMap.Scale());
          this.map.addControl(new AMap.ToolBar());
          this.map.addControl(
            new AMap.Geolocation({
              position: {
                bottom: "100px",
                right: "20px",
              },
            })
          );
          this.map.addControl(
            new AMap.ControlBar({
              position: {
                top: "80px",
                right: "20px",
              },
            })
          );

          this.map.on("click", (e) => {
            if (this.allEvent) {
              this.lngLat = e.lnglat;
            }
          });
          this.map.on("mouseover", () => {
            if (this.allEvent) {
              this.contextMenu.close();
            }
          });
          this.map.on("zoomchange", (e) => {
            if (this.marker) {
              this.map.remove(this.marker);
            }
          });
          this.map.on("dragstart", () => {
            this.cursor = false;
          });
          this.map.on("dragend", () => {
            this.cursor = true;
          });
          //初次加载天河区
          this.districtSearch("天河区");

          this.setMouseRight();
        })
        .catch((e) => {
          console.log(e);
        });
    },
    // 行政区区域划分
    districtSearch(newValue) {
      // console.log("districtSearch", newValue);
      new Promise((resolve, reject) => {
        //加载行政区划插件
        if (!this.$DistrictSearch) {
          //实例化DistrictSearch
          var opts = {
            subdistrict: 0, //获取边界不需要返回下级行政区
            extensions: "all", //返回行政区边界坐标组等具体信息
            level: "district", //查询行政级别为 *
          };
          this.map.plugin(["AMap.DistrictSearch"], () => {
            this.$DistrictSearch = new AMap.DistrictSearch(opts);
            resolve();
          });
        } else {
          resolve();
        }
      }).then(() => {
        //行政区查询
        this.$DistrictSearch.search(newValue, (status, result) => {
          if (this.currentAdcode == result.districtList[0].adcode) return;
          if (this.polygons) {
            this.map.remove(this.polygons);
          }
          this.polygons = [];
          this.currentAdcode = result.districtList[0].adcode;
          var bounds = result.districtList[0].boundaries;
          if (bounds) {
            for (var i = 0, l = bounds.length; i < l; i++) {
              //生成行政区划polygon
              var polygon = new AMap.Polygon({
                strokeWeight: 1,
                path: bounds[i],
                fillOpacity: 0.4,
                fillColor: "#80d8ff",
                strokeColor: "#0091ea",
              });
              polygon.on("click", () => {
                if (!this.allEvent) return;
                if (this.marker) {
                  this.map.remove(this.marker);
                }
                this.map.setFitView();
              });
              polygon.on("rightclick", (e) => {
                if (this.allEvent) {
                  this.contextMenu.open(this.map, e.lnglat);
                }
              });
              this.polygons.push(polygon);
            }
            this.placeSearch(result.districtList[0].adcode);
          }
          this.partList = [];
          this.map.add(this.polygons);
          this.map.setFitView(this.polygons); //视口自适应
        });
      });
    },
    // poi查询
    placeSearch(adcode) {
      // console.log("placeSearch", adcode);
      const p = new Promise((resolve, reject) => {
        if (!this.PlaceSearch) {
          this.map.plugin(["AMap.PlaceSearch"], () => {
            this.PlaceSearch = new AMap.PlaceSearch({
              //设置PlaceSearch属性
              // map: this.map,
              city: "广州", //城市
              type: "", //数据类别
              pageSize: 50, //每页结果数,默认10
              pageIndex: 1, //请求页码，默认1
              extensions: "all", //返回信息详略，默认为base（基本信息）
              autoFitView: false, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
            }); //构造地点查询类
            resolve();
          });
        } else {
          resolve();
        }
      });
      let partList = [];
      p.then(() => {
        return new Promise((resolve, reject) => {
          this.PlaceSearch.setPageIndex(1);
          this.PlaceSearch.setCity(adcode);
          this.PlaceSearch.search("公园", (status, result) => {
            if (status === "complete" && result.poiList) {
              let index = Math.ceil(result.poiList.count / 50);
              partList = result.poiList.pois;
              let times = index;
              if (index > 1) {
                for (let i = 2; i <= index; i++) {
                  this.PlaceSearch.setPageIndex(i);
                  this.PlaceSearch.search("公园", (status, res) => {
                    partList = [...partList, ...res.poiList.pois];
                    times--;
                    if (times == 1) resolve();
                  });
                }
              } else {
                resolve();
              }
            } else {
              reject();
              console.error("根据经纬度查询地址失败");
            }
          }); //关键字查询查询
        });
      }).then(() => {
        this.partList = partList;
        this.markerClusterer(partList);
        this.show = true;
        this.routeShow = true;
      });
    },
    // 点聚合
    markerClusterer(arr) {
      // console.log("markerClusterer");
      let points = [];
      for (let i = 0; i < arr.length; i++) {
        points.push({
          lnglat: [arr[i].location.lng, arr[i].location.lat],
          id: i,
        });
      }
      let opt = [
        {
          url: "//a.amap.com/jsapi_demos/static/images/blue.png",
          size: new AMap.Size(32, 32),
          offset: new AMap.Pixel(-16, -16),
        },
        {
          url: "//a.amap.com/jsapi_demos/static/images/green.png",
          size: new AMap.Size(32, 32),
          offset: new AMap.Pixel(-16, -16),
        },
        {
          url: "//a.amap.com/jsapi_demos/static/images/orange.png",
          size: new AMap.Size(36, 36),
          offset: new AMap.Pixel(-18, -18),
        },
        {
          url: "//a.amap.com/jsapi_demos/static/images/red.png",
          size: new AMap.Size(48, 48),
          offset: new AMap.Pixel(-24, -24),
        },
        {
          url: "//a.amap.com/jsapi_demos/static/images/darkRed.png",
          size: new AMap.Size(48, 48),
          offset: new AMap.Pixel(-24, -24),
        },
      ];
      if (!this.MarkerClusterer) {
        //添加聚合组件
        this.map.plugin(["AMap.MarkerClusterer"], () => {
          this.MarkerClusterer = new AMap.MarkerClusterer(
            this.map, // 地图实例
            points, // 海量点数据，数据中需包含经纬度信息字段 lnglat
            { styles: opt }
          );
          this.MarkerClusterer.on("click", (e) => {
            if (!this.allEvent) return;
            if (e.clusterData.length > 1) {
              let marker = [];
              for (let k = 0; k < e.clusterData.length; k++) {
                marker.push(
                  new AMap.Marker({
                    position: e.clusterData[k].lnglat,
                  })
                );
              }
              this.map.setFitView(marker, false, [150, 60, 100, 60]);
            } else {
              let name = this.partList[e.clusterData[0].id].name;
              if (this.marker) {
                this.map.remove(this.marker);
              }
              this.marker = new AMap.Marker({
                position: e.clusterData[0].lnglat,
                label: {
                  direction: "right",
                  offset: new AMap.Pixel(10, 0), //设置文本标注偏移量
                  content: name, //设置文本标注内容
                },
              });
              this.currentPart = this.partList[e.clusterData[0].id];
              this.dir_to = name;
              this.show = false;
              this.map.setCenter(e.clusterData[0].lnglat);
              this.map.add(this.marker);
              // this.map.setFitView(e.marker, false, [150, 60, 100, 60]);
            }
          });
        });
      } else {
        this.MarkerClusterer.setData(points);
      }
    },
    // 解析坐标->地址，获取所在区
    geoCoder(location) {
      // console.log("getAddress");
      //加载插件
      new Promise((resolve, reject) => {
        if (!this.Geocoder) {
          this.map.plugin(["AMap.Geocoder"], () => {
            this.Geocoder = new AMap.Geocoder({
              city: "广州市",
            });
            resolve();
          });
        } else {
          resolve();
        }
      }).then(() => {
        this.Geocoder.getAddress(location, (status, result) => {
          if (status === "complete" && result.regeocode) {
            let district = result.regeocode.addressComponent.district;
            if (!district) district = result.regeocode.addressComponent.city;
            this.districtSearch(district);
          } else {
            console.error("根据经纬度查询地址失败");
          }
        });
      });
    },
  },
  mounted() {
    //DOM初始化完成进行地图初始化
    this.initMap();
    // console.log("vm",this)
  },
  created() {
    this.$bus.$on("share_id", (val) => {
      this.autoOptions.input = val;
    });
  },
  watch: {
    lngLat(newVal) {
      console.log("点击了");
      this.geoCoder(newVal);
    },
  },
};
</script>

<style lang="less">
*::-webkit-scrollbar {
  display: none;
}
.amap-logo,
.amap-copyright {
  display: none !important;
}
#container {
  padding: 0px;
  margin: 0px;
  width: 100%;
  height: 100vh;
}
.cursordown {
  cursor: url("//webmap0.bdimg.com/image/api/openhand.cur") 8 8, default !important;
}
.cursorup {
  cursor: url("//webmap0.bdimg.com/image/api/closedhand.cur") 8 8, move !important;
}

#part-detail {
  width: 360px;
  min-height: 360px;
  max-height: 500px;
  position: fixed;
  top: 15px;
  left: 15px;
  z-index: 999;
  overflow-x: hidden;
  overflow-y: scroll;
  scrollbar-width: none;
  background-color: #fff;
  box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15);
  border-radius: 3px;
  #placereturnfixed {
    z-index: 10001;
    padding: 3px 7px 3px 5px;
    cursor: pointer;
    font-size: 13px;
    display: inline-block;
    background-color: rgba(51, 51, 51, 0.5);
    border-radius: 2px;
    color: #fff;
    position: absolute;
    top: 6px;
    left: 10px;
  }
  #info-box {
    height: 100%;
    #go-btn {
      position: absolute;
      right: 8px;
      top: 174px;
      width: 54px;
      height: 54px;
      background-color: #0e89f5;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      border-radius: 50%;
      color: #fff;
      cursor: pointer;
      user-select: none;
      box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
      transition: box-shadow 0.15s cubic-bezier(0.4, 0, 1, 1);
    }
  }
}

#part-route {
  position: fixed;
  display: flex;
  top: 15px;
  left: 15px;
  z-index: 99;
  align-items: center;
  width: 360px;
  height: 215px;
  background-color: #3d93fd;
  flex-direction: column;
  box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15);
  border-radius: 3px 3px 0 0;
  #close-route {
    position: absolute;
    z-index: 10002;
    width: 25px;
    height: 25px;
    font-size: 20px;
    line-height: 20px;
    top: 10px;
    right: 10px;
  }

  #close-route:hover {
    color: red;
    cursor: pointer;
  }
  .goway {
    padding-top: 20px;
    display: flex;
    justify-content: space-around;
  }
  .line-search-from {
    position: relative;
    padding-left: 10px;
    height: 34px;
    line-height: 34px;
    background-color: #3587eb;
    width: 270px;
    font-size: 14px;
    color: #acd7ff;
    border-radius: 2px;
    margin-bottom: 10px;
    .dir_ipt {
      width: 90%;
      height: 34px;
      line-height: 32px;
      border: none;
      text-indent: 5px;
      background-color: #3587eb;
      color: #acd7ff;
      padding: 0;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
  #to-btn {
    position: absolute;
    bottom: 10px;
    right: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 32px;
    width: 50px;
    line-height: 32px;
    background-color: #559ffb;
    border: none;
    border-radius: 2px;
    color: #fff;
    font-size: 14px;
    text-decoration: none;
    user-select: none;
    box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.21);
    -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.21);
    -moz-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.21);
  }
}

#route-info {
  position: fixed;
  top: 230px;
  left: 15px;
  z-index: 99;
  width: 360px;
  max-height: 300px;
  overflow: scroll;
  scrollbar-width: none;
  background-color: #3d93fd;
  box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15);
  border-radius: 3px 3px 0 0;
  .poi-more,
  .amap-call,
  .clearfix {
    display: none !important;
  }
  .plan {
    overflow-y: scroll;
    scrollbar-width: none;
    height: 300px;
  }
}

.anim-down {
  -webkit-animation-name: layui-down;
  animation-name: layui-down;
  -webkit-animation-duration: 0.3s;
  -webkit-animation-fill-mode: both;
  animation-duration: 0.3s;
  animation-fill-mode: both;
}
@-webkit-keyframes layui-down {
  from {
    -webkit-transform: translateY(-100%);
    opacity: 0.3;
  }
  to {
    -webkit-transform: translateY(0);
    opacity: 1;
  }
}
@keyframes layui-down {
  from {
    transform: translateY(100%);
    opacity: 0.3;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
</style>